Tools Plus lets your application implement and support the Macintosh’s pull-down menus with less effort than ordinary C or Pascal. A menu is created by using the Menu procedure. First, the name that appears in the menu bar is specified, along with a menu number, which can be from 1 to 15. The menu number refers to that specific menu until the menu is deleted. Menu items can then be added to a specific menu. In this document, the term menu refers to the name that appears in the menu bar, whereas the term menu item or item refers to individual items found within a menu. The item number is determined by counting from the top of the list, the first item being 1, the second being 2, etc.
An entire menu can be deleted by using the RemoveMenu procedure. This procedure reclaims the memory previously used by the menu. Individual items can also be deleted using this procedure.
Menu items can also be inserted between others. This lets your application maintain a dynamic menu that may be used, for example, for a list of open document names.
Menu items can be renamed by using the RenameItem procedure. This should be done judicially, since changes to menus and/or menu items may prove to be confusing to the user.
A menu or menu item can be enabled or disabled. When a menu is disabled, it is dimmed along with all its associated items and cannot be selected. When an item is disabled, it becomes dim and cannot be selected.
Various other menu item-related features are supported, such as “check marks” (CheckMenu procedure), other marks (MenuMark procedure), and item styling (MenuStyle procedure).
After changes have been made to the menu bar by adding/deleting or enabling/disabling menus (not items), the UpdateMenuBar procedure should be called to display those changes on the menu bar.
Note: This version of Tools Plus does not support hierarchic (cascading)
menus.
Menus and MultiFinder or System 7
``````````````````````````````````
Both MultiFinder (running under System 5 or 6) and System 7 can automatically interact with your application through its menus. If your application is running while the user double-clicks (or select-opens) one of your application’s documents from the Finder, the affected document is automatically opened by your application. Also, if the user selects the Special menu’s Restart or Shut Down command while your application is running, it will be instructed to quit.
In both these cases, the system simulates the selection of a menu item. You must have a File menu with an item named “Open…” (including the ellipsis, Option-; character), and the last item named “Quit”. In the case of opening a document, PollSystem returns a doMenu event to your application indicating that the File menu’s “Open…” command was selected, in which case your application would do whatever is appropriate, likely display an SFGetFile dialog to let the user choose which file to open. The system fools your application into thinking that the double-clicked file was selected from an SFGetFile dialog (which is not actually displayed). When the user selects Restart or Shut Down, PollSystem returns a doMenu event to your application indicating that the File menu’s “Quit” command was selected, in which case your application would do whatever is appropriate, such as asking if open documents should be saved before quitting.
If your application does not [1] open files by using the File menu’s “Open…” command, or [2] quit by using the File menu’s “Quit” command, see the chapter on “Completing Your Application,” where you can remap these functions to other menu items.
See the chapter on “Completing Your Application.” The section on “bundles” defines the association between your application and the files it creates, while the section on ‘mstr’ resources details remapping the ‘Open…’ and ‘Quit’ functions to other menu items.
Edit Menu
`````````
The Edit menu has a high degree of consistency across all Macintosh applications in appearance and function. Your application should have an Edit menu if your application:
• has two or more menus in the title bar (excluding the Apple menu)
• uses editing fields
• supports desk accessories and runs under systems prior to System 7
It is good form to include an Edit menu in your application even if you don’t support its functions, just for the user’s familiarity.
Your application’s second menu must be called “Edit.” The Edit menu must contain the items “Undo”, “Cut”, “Copy”, “Paste” and “Clear” as the first five items in the listed order. A dividing line must exist between “Undo” and “Cut”. Tools Plus automatically enables and disables items in the Edit menu as described in the “Editing Fields” chapter under The Edit Menu whenever an editing field is active. It also automatically changes the “Undo” item to “Can’t Undo” when:
• a modeless window is created or closed
• an inactive window is activated
• an editing field is deactivated or activated (including selecting a
new editing field)
• a desk accessory performs a Cut or Copy operation which affects the
clipboard
Your application is responsible for maintaining the Edit menu whenever it is not interacting with an active editing field. For example, if your application performs a function that can’t be undone, it should set the “Undo” item “Can’t Undo.” Also, if it performs an operation that can be undone, it should change the “Undo” item to whatever is appropriate, such as “Undo Merging.” The other items in the Edit menu, namely “Cut”, “Copy”, “Paste”, and “Clear” should be enabled/disabled as required.
Note: Do not rename the Edit menu’s “Undo” item, or change the
enabled/disabled state of the Edit menu’s “Undo”, “Cut”, “Copy”,
“Paste”, or “Clear” items if the active window is modeless and it
contains an active editing field. Tools Plus maintains these menu
items automatically. If you are going to make such a change,
preface it by a call to GetFieldString (to retrieve the active
field’s edited text for validation by your application), a call to
SaveFieldString (to save the edited text as the field’s associated
string), then to DeactivateField (to deactivate the window’s
active field and end automatic maintenance of the Edit menu).
Desk Accessories
````````````````
You can give your application the ability to use desk accessories (DA) by installing the Apple menu. Although desk accessory activity is handled entirely by Tools Plus, your application must adhere to some very strict rules. Your application must have at least two menus to ensure compatibility with System 6 and prior. The first menu is called “File”, and must contain “Quit” as the last item. The second menu must be the “Edit” menu, as described above. The edit menu must exist as described, even if your application does not support these commands. Lastly, you must ensure that sufficient free space exists in the menu bar to accommodate additional menus, since some DAs create their own menus when running under System 6 or prior. Complying with these requirements will ensure that your application is compatible with desk accessories in all system versions.
Desk accessories affect the Edit menu as described later in this chapter under “Effect of Desk Accessories on Menus.”
For more details about desk accessory interaction, see the PollSystem function.
Editing Fields
``````````````
If your application is going to use editing fields, an “Edit” menu will greatly assist in text editing. The Edit menu is detailed earlier in this chapter.
Menus and Editing Fields
````````````````````````
The Edit menu automatically performs all editing operations between the active editing field and the Clipboard. This includes:
• Cutting the selected text from the active editing field and placing
it on the Clipboard
• Copying the active editing field’s selected text to the Clipboard
• Pasting the Clipboard’s contents into the active editing field
• Undoing the last operation, including the Edit menu’s Cut, Copy,
Paste, and Clear operations, as well as typing and using the Delete
(or Backspace) key
• Redoing the last Undo operation
This functionality is detailed in the “Editing Fields” chapter of this manual.
When a modeless window is activated, or when an editing field is activated on the active window, the Edit menu is automatically updated to reflect the operations that can be performed on the active field. Any editing done within the field automatically updates the Edit menu’s items. If an active, modeless window containing an active editing field is deactivated, either by being closed or by activating another modeless window without an active field, all 5 items are disabled.
Opening and closing modal windows does not affect the Edit menu, since menus cannot be accessed while a modal window is active.
Menus and Desk Accessories (Using Finder under System 5 or 6)
This section applies only when your application is running under Finder (not MultiFinder) under System 5 or 6. Tools Plus automatically maintains the Edit menu as per the Macintosh user-interface guide-lines (described below).
When a desk accessory becomes the active window, the Edit menu’s “Undo” item name, and the enabled/ disabled status of the “Cut”, “Copy”, “Paste” and “Clear” items are temporarily stored. The undo item is renamed to “Undo”. This is done in view that the item may have read “Undo Typing” or some other specific action that does not pertain to a desk accessory. The “Cut”, “Copy”, “Paste” and “Clear” items are all enabled for the desk accessory’s use. When the desk accessory becomes inactive, either by being closed or by activating another window, the Edit menu is restored to its original state.
Command Key Equivalents
```````````````````````
Menus can be invoked from the keyboard by setting up a Command key equivalent. The character you specify for a Command key equivalent will likely be a letter, however, other characters may be used. When the user holds down the Command key and types a letter, whether in upper or lower case, the equivalent menu item is invoked as if the menu had been pulled down and selected. The user just sees the appropriate name in the menu bar highlighted while the operation takes place.
The system responds equally to shifted or non-shifted characters. For example, Command-C and Command-c both invoke the same menu item. Consequentially, Command-+ is read by the system as Command-=. For consistency between applications, upper case letters should be used.
Command-Shift-number combinations are not Command key equivalents, because they are processes as a separate type of event (this is why Command-Shift-1 and 2 eject the internal and external floppy disk). Although unshifted Command-number equivalents can be used, they should be used judicially to avoid confusion.
Note: Several Command key equivalents are reserved for specific
Tools Plus takes care of maintaining the Edit menu when an editing field is active on a modeless window. Use the PollSystem function to constantly inquire about any requests the system may have. When a menu item is selected by the user, the corresponding menu name in the menu bar is highlighted and PollSystem returns the menu number and menu item number selected by the user. This also occurs if the user types the Command key equivalent of a menu. After your application has responded to the selection, call MenuHilite(0) to un-highlight the menu bar.
If Undo, Cut, Copy, Paste, or Clear are selected while an editing field is active, Tools Plus automatically processes the command and an event is not reported to your application.
Under MultiFinder or System 7, the user can double-click one of your application’s documents while your application is running. This generates a doMenu event that is equivalent to the File menu’s “Open…” item in your application.
The user can also select the Special menu’s Restart or Shut Down commands, which generates a doMenu event that is equivalent to the File menu’s “Quit” item, instructing your application to quit.
See the PollSystem function for complete details on the handling of menus.
This procedure searches the system for all desk accessories, then place their names in the “Apple” menu. AppleMenu should be called prior to defining any other menus. If the Apple menu has already been created, AppleMenu does nothing.
AboutName specifies the title of the Apple menu’s “About” item, such as “About The Application...” This item will be the first in the Apple menu, followed by a dividing line, then by the desk accessories listed in alphabetic order. If AboutName is a null string, only the desk accessory names will appear in the Apple menu.
In order to prevent the menu bar from flickering each time a new menu is added, this procedure does not immediately display the Apple menu in the menu bar. When you have finished making changes to the menu bar (by using the Menu and/or RemoveMenu procedures), call UpdateMenuBar to display the changes made to the menu bar. Your application will receive a doMenu event when the user selects the Apple menu’s “About” item.
See “Desk Accessories” at the beginning of Menus for desk accessory menu requirements.
When a menu is first created, the title in the menu bar must be defined. This is done by calling the Menu procedure with ItemNumber having a value of zero (0). Menu items are then added to the menu. Your application should define menu items in their correct order (ie. top to bottom) in order to use the full power of this procedure.
MenuNumber specifies the menu number (from 1 to 15) that is affected. Once a menu is created, it will be referenced by this menu number. Menu names in the menu bar are displayed left to right in the ascending order of their MenuNumber, with the Apple menu (if one was created) in the leftmost position.
ItemNumber specifies the menu item number (from 1 to 255) that is affected. If ItemNumber is zero (0), the Menu procedure refers to the menu’s name in the title bar.
EnabledFlag specifies whether the menu/item is enabled or disabled. The menu/item can be selected only when enabled. When disabled, the menu/item is dimmed and cannot be selected by the user. The two constants that can be used for this purpose are enabled and disabled. If the ItemNumber is zero, the action applies to all items within the specified menu. When the menu later becomes enabled, all items in the menu assume their correct enabling/disabling as specified by your application. Menus and menu items can be enabled and disabled by using the EnableMenu procedure.
MenuText is the name of the menu/item. When a menu item is first created (ie. when the Menu procedure is called the first time for an item within a menu), special “Meta-Characters” are recognized by the system. You may choose to include or exclude these characters within MenuText, however, you should be aware of their effects. Multiple Meta-Characters may be included in MenuText.
Meta Characters
```````````````
Meta-Characters are recognized only when a menu item is first created. They are not interpreted when creating the menu’s name (which appears in the title bar) or when a menu item is renamed. If you want any of the meta-characters to appear in a menu’s text, first create a blank menu item (MenuText equals a space), then change the item’s text with the Menu or RenameItem routine to include the desired characters.
The semi-colon (;) and Return character ($0D) cannot be used as meta-characters. The following is a list of meta-characters…
^ Display an icon to the left of the menu item. The number following
the caret (^) should be from 1 to 255. Note that icon numbers 257
to 511 are reserved for applications, and that the Menu Manager
adds 256 to the icon number you specify.
! Display a special mark to the left of a menu item name. The single
character that follows the exclamation mark (!) is displayed.
The check mark is the default. (It is best to use the CheckMenu or
MenuMark procedures.)
< The item is displayed in a special character style. The single
character that follows specifies the style (<B for Bold, <I for
Italics, <U for Underline, <O for Outline, and <S for Shadow).
Multiple styles can be combined, such as “<B<I” for “bold and
italics.” It is best to use MenuStyle to change styles.
/ The slash (/) indicates that a menu item may be invoked by using a
keyboard equivalent. The single character that follows the slash
specifies the command key equivalent to a menu item. For
consistency, use upper case letters. Also, shifted characters are
ignored. Therefore, Command-+ is interpreted as Command-=.
To create a “dividing line” between sections of related menu items, disable the menu item and use ‘-’ (a minus or dash) as the MenuText value.
Special care should be taken to define the menu’s name in the title bar first, then to define menu items in their correct sequential order. If a menu item is defined without first defining the menu’s name, the name in the title bar is automatically defined as “Menu x” where x is the menu number. Also, if any menu items are skipped when defining a menu item (i.e. creating menu item 3 without first creating 1 and 2) the missing menu items (1 and 2) are automatically created as blank, disabled items. Consequentially, Meta-Characters will not be recognized when the Menu procedure references these automatically created menus; the Menu procedure will simply rename the existing item.
A menu’s name (which appears in the menu bar) cannot be changed. If the menu’s name must be changed, the affected menu must be removed with the RemoveMenu procedure, then re-created as required by using the Menu procedure.
In order to prevent the menu bar from flickering each time a new menu is added, this procedure does not immediately display the new menu in the menu bar. When you have finished making changes to the menu bar (by using the Menu and/or RemoveMenu procedures), call UpdateMenuBar to display the changes made to the menu bar.
MenuNumber specifies the menu number (from 1 to 15) where the menu item will be created. If the menu does not exist, InsertMenuItem does nothing.
ItemNumber specifies the menu item number (from 1 to 255) where the item will be inserted. If the menu item does not exist in the specified menu, InsertMenuItem does nothing. InsertMenuItem will append one item to the end of a menu if the ItemNumber equals the current number of items plus 1.
EnabledFlag specifies whether the item is enabled or disabled. In the enabled state, the item can be selected whereas in the disabled state, the item is dimmed and cannot be selected by the user. The two constants that can be used for this purpose are enabled and disabled. Menus and menu items can be enabled and disabled by using the EnableMenu procedure.
MenuText is the name of the item. Special “Meta-Characters” that may be imbedded in the text are detailed in the Menu procedure.
When the item is inserted, all existing items starting at ItemNumber will be pushed down one space to make room for the new item. This means that their menu number will be changed. The new item is inserted at the location specified by ItemNumber. The main use for this procedure is to let your application maintain a dynamic menu, such as a list of open document names.
MenuNumber specifies the menu number (from 1 to 15) that is affected. If the menu does not exist, RemoveMenu does nothing.
ItemNumber specifies the menu item number (from 1 to 255) that is deleted. If ItemNumber is zero (0), RemoveMenu refers to the menu’s name in the title bar and all its associated items. If the menu item is not zero and does not exist, RemoveMenu does nothing.
If a menu is deleted along with its associated items (i.e. when ItemNumber = 0), any menus with higher menu numbers will be shifted to the left to fill in the space occupied by the deleted menu. Their menu numbers, however, remain unchanged.
In order to prevent the menu bar from flickering each time a menu is removed, this procedure does not immediately display the altered menu bar. When you have finished making changes to the menu bar (by using the Menu and/or RemoveMenu procedures), call UpdateMenuBar to display the changes made to the menu bar.
Note: Use RemoveMenu to maintain a dynamic menu, such as a list of open
windows. Do not use it to make items unavailable. Instead,
Display the menu bar with the changes made by the Menu procedure, RemoveMenu procedure, or EnableMenu procedure (when enabling/disabling an entire menu).
pascal void UpdateMenuBar(void);
procedure UpdateMenuBar;
The UpdateMenuBar procedure is not performed automatically because the menu bar flickers slightly whenever it is updated. If several updates were to be performed in a row (by creating several new menus at the beginning of a program, for example, or enabling/disabling several menus), the repeated flicker would be quite annoying. The UpdateMenuBar procedure should be called when your application is finished creating, deleting, or enabling/disabling menus. UpdateMenuBar automatically resets a highlighted menu in the menu bar. Changes made to individual menu items do not require a call to UpdateMenuBar.
MenuNumber specifies the menu number (from 1 to 15) in which the menu item will be changed. If the menu number does not exist, RenameItem does nothing.
ItemNumber specifies the menu item number (from 1 to 255) which will be changed. If the item number does not exist within the menu specified by MenuNumber, RenameItem does nothing.
MenuText specifies the menu item’s new name. MenuText may be blank, but should never be a null string. The item’s state (enabled/disabled), style (bold, underline, etc.), icon and command key equivalent are not changed. Meta-Characters are not interpreted by this procedure.
RenameItem does not change the menu’s in the menu bar. If the menu’s name must be changed, the affected menu must be removed with the RemoveMenu procedure, then re-created as required by using the Menu procedure.
MenuNumber specifies the menu number (from 1 to 15) in which the enabling/disabling will take place. If the menu number does not exist, EnableMenu does nothing.
ItemNumber specifies the menu item number (from 1 to 255) which is enabled/ disabled. A value of zero (0) affects the title in the menu bar. If ItemNumber is not zero and the item number does not exist within the menu specified by MenuNumber, EnableMenu does nothing.
EnabledFlag specifies whether the menu/item is enabled or disabled. In the enabled state, the menu/item can be selected. In the disabled state, the menu/item is dimmed and cannot be selected by the user. The two constants that can used for this purpose are enabled and disabled. If the ItemNumber is zero, the disabling of the menu applies to all items within that menu. When the menu later becomes enabled, all items in the menu assume their correct enabling/disabling as specified by your application.
This procedure does not change the menu bar if any of the menus are enabled/disabled by using an ItemNumber equal to zero (0). This is done in order to prevent the menu bar from flickering each time a menu is enabled or disabled. When you have finished making changes to the menu bar (by using the Menu, RemoveMenu, or EnableMenu procedures) call UpdateMenuBar to display the changes made to the menu bar.
MenuNumber specifies the menu number (from 1 to 15) that is affected. If the menu number does not exist, CheckMenu does nothing.
ItemNumber specifies the menu item number (from 1 to 255) that is affected. If the item number does not exist within the menu specified by MenuNumber, CheckMenu does nothing.
Checked specifies whether the menu item’s check mark is displayed or hidden. The two constants that can be used for this purpose are on and off.
To display characters other than the standard check mark, use the MenuMark procedure.
Display or hide a special character to the left of a menu item’s name. This procedure is used instead of CheckMenu when a character other than the default check mark is to be displayed/hidden.
pascal void MenuMark (int MenuNumber, int ItemNumber, int markChar);
MenuNumber specifies the menu number (from 1 to 15) that is affected. If the menu number does not exist, MenuMark does nothing.
ItemNumber specifies the menu item number (from 1 to 255) that is affected. If the item number does not exist within the menu specified by MenuNumber, MenuMark does nothing.
MarkChar specifies the character that is to be displayed. The following constants are available for menu marks:
CONST {Menu Item characters }
AppleChar = char($14); {Apple character }
CheckChar = char($12); {Check Mark character }
DiamondChar = char($13); {Diamond character }
DotChar = char($A5); {Dot (or bullet) character }
NoChar = char($00); {no character (remove a character) }
MenuNumber specifies the menu number (from 1 to 15) that is affected. If the menu number does not exist, MenuStyle does nothing.
ItemNumber specifies the menu item number (from 1 to 255) that is affected. If the item number does not exist within the menu specified by MenuNumber, MenuStyle does nothing.
TheStyle specifies the style(s) in which the menu item is to be displayed. Special character constants defined by the font manager are bold, italic, underline and shadow. C programmers will use the font manager’s constants to specify a composite style, such as MenuStyle(1,1,bold+outline) for bold and outlined, or MenuStyle(1,1,0) for plain text. Pascal programmers will use the font manager’s constants to specify a set, such as MenuStyle(1,1,[bold,outline]) for bold and outlined, or MenuStyle(1,1,[]) for plain text.
Highlight a menu in the menu bar, or remove the current highlight from the menu bar.
pascal void MenuHilite (int MenuNumber);
procedure MenuHilite(MenuNumber: INTEGER);
MenuNumber specifies the menu number (from 1 to 15) that will be highlighted. Since only one menu can be highlighted at a time, any other highlighted menu is automatically unhighlighted. Specifying a MenuNumber of zero (0) unhighlights the currently highlighted menu. If the menu number does not exist and is not zero (0), MenuHilite does nothing.